package com.tony.pmp.server.aspect;

import com.tony.pmp.common.utils.IPUtil;
import com.tony.pmp.model.entity.SysLogEntity;
import com.tony.pmp.server.annotation.LogAnnotation;
import com.tony.pmp.server.service.SysLogService;
import com.tony.pmp.server.shiro.ShiroUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.google.gson.Gson;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.lang.reflect.Method;

/**
 * Created with IntelliJ IDEA.
 *
 * @Title: LogAscept
 * @Auther: 皮蛋布丁
 * @Date: 2021/08/02/20:47
 * @Description: 日志任务切面处理类
 */
@Aspect
@Component
public class LogAspect {

    @Autowired
    private SysLogService sysLogService;

    /**
    * @Description: logPointCut 切点
    * @Param: []
    * @return: void
    * @Author: 皮蛋布丁
    * @Date: 2021/8/2 20:53
    */
    @Pointcut("@annotation(com.tony.pmp.server.annotation.LogAnnotation)")
    public void logPointCut() {

    }

    /**
    * @Description: arount 环绕通知
    * @Param: [point]
    * @return: java.lang.Object
    * @Author: 皮蛋布丁
    * @Date: 2021/8/2 20:55
    */
    @Around("logPointCut()")
    public Object arount(ProceedingJoinPoint point) throws Throwable{
        long start = System.currentTimeMillis();

        Object result = point.proceed();

        long time = System.currentTimeMillis() - start;

        saveLog(point,time);

        return result;
    }

    /**
    * @Description: saveLog 保存日志
    * @Param: [point, time]
    * @return: void
    * @Author: 皮蛋布丁
    * @Date: 2021/8/2 20:56
    */
    private void saveLog(ProceedingJoinPoint point,Long time) {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();

        SysLogEntity logEntity = new SysLogEntity();

        //获取请求操作的描述信息
        LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);
        if (logAnnotation != null) {
            logEntity.setOperation(logAnnotation.value());
        }

        //获取操作方法名
        String className = point.getTarget().getClass().getName();
        String methodName = signature.getName();
        logEntity.setMethod(new StringBuilder(className).append(".").append(methodName).append("()").toString());

        //获取请求参数
        Object[] args = point.getArgs();
        String params = new Gson().toJson(args[0]);
        logEntity.setParams(params);

        //获取ip地址
        logEntity.setIp(IPUtil.getIpAddr(((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest()));

        //获取剩下的参数
        logEntity.setCreateDate(DateTime.now().toDate());
        String userName = ShiroUtil.getUserEntity().getUsername();
        logEntity.setUsername(userName);

        //执行时间
        logEntity.setTime(time);
        sysLogService.save(logEntity);
    }

}
